#pragma once

#include <iostream>
#include <string>
#include <list>
#include "InetAddr.hpp"
#include "Log.hpp"
#include <sys/types.h>
#include <sys/socket.h>
using namespace LogModule;

class UsertInterface
{
public:
    virtual ~UsertInterface() = default;
    virtual void SendTo(int sockfd, const std::string& message) = 0;
    virtual bool operator==(const InetAddr &) const = 0;
};

class User : public UsertInterface
{
public:
    User(const InetAddr &id) : _id(id)
    {
    }
    void SendTo(int sockfd, const std::string &message)
    {
        LOG(LogLevel::DEBUG) << "send message to " << _id.Addr() << "Info: " << message;
        int n = sendto(sockfd, message.c_str(), message.size(), 0, _id.NetAddr(), _id.NetAddrLen());
        (void)n;    
    }
    bool operator==(const InetAddr &u) const override
    {
        return _id == u;
    }

    ~User()
    {
    }

private:
    InetAddr _id;
};

// 对用户消息进行路由
// 用该类把所有用户先管理起来
// 观察者模式，observer
// 所有的User相当于观察者，一旦有某种事件发生了，其中，我要作为一个观察者，我把我加到这个_online_users当中，一旦未来有某些事发生了
// UserManager得通知我，即通过Router函数。
class UserManager
{
public:
    UserManager()
    {
    }
    void AddUser(const InetAddr &id)
    {
        for (auto &user : _online_users)
        {
            if (*user == id)
            {
                LOG(LogLevel::INFO) << id.Addr() << "用户已经存在";
                return;
            }
        }
        LOG(LogLevel::INFO) << "新增该用户 " << id.Addr();  
        _online_users.push_back(std::make_shared<User>(id)); // 构建一个User对象
    }

    void DelUser(const InetAddr &user)
    {
    }
    void Router(int sockfd,const std::string &message)
    {
        for (auto &user : _online_users)
        {
                user->SendTo(sockfd, message); // 通过User自己的函数发消息
        }
    }
    ~UserManager()
    {
    }

private:
    std::list<std::shared_ptr<UsertInterface>> _online_users;
};